package main

type X struct {
	a int
}

type Y struct {
	X
	b int
}

type Z struct {
	Y
	c int
}

/**
从前面讨论的命名类型的方法可知，使用 type 定义的新类型不会继承原有类型的方法，有个特例就是命名结构类型，命名结构类型可以嵌套其他的命名类型的字段，
外层的结构类型是可以调用嵌入字段类型的方法，这种调用既可以是显式的调用，也可以是隐式的调用。这就是 Go 的“继承”，准确地说这就是 Go 的“组合”。

因为Go语言没有继承的语义，结构和字段之间是“has k”的关系，而不是“is a”的关系；没有父子的概念，仅仅是整体和局部的概念，所以后续统称这种嵌套的结构和
字段的关系为组合。

struct 中的组合非常灵活，可以表现为水平的字段扩展，由于 struct 可以嵌套其他 struct 字段，所以组合也可以分层次扩展。struct 类型中的字段称为“内嵌
字段”，内嵌字段的访问和方法调用遵照的规约接下来进行讲解。

内嵌字段的初始化和访问

struct 的字段访问使用点操作符“.”，struct 的字段可以嵌套很多层，只要内嵌的字段是唯一的即可，不需要使用全路径进行访问。在以下示例中，可以使用 z.a 代替 z.Y.X.a
*/
func main() {
	x := X{a: 1}
	y := Y{
		X: x,
		b: 2,
	}
	z := Z{
		Y: y,
		c: 3,
	}
	//z.a, z.Y.a, z.Y.X.a 三者是等价的， z.a z.Y.a 是 z.Y.X.a 的简写
	println(z.a, z.Y.a, z.Y.X.a) //1 1 1
	z = Z{}
	z.a = 2
	println(z.a, z.Y.a, z.Y.X.a) //2 2 2
}
